package com.platform.core.service.impl;

import cn.hutool.core.util.StrUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.platform.comm.dto.DtoMapper;
import com.platform.comm.entity.CommDataInfoEntity;
import com.platform.comm.jwt.TokenInfoUtil;
import com.platform.comm.service.ICommDataInfoBiz;
import com.platform.core.entity.NcloudSysNotifyEntity;
import com.platform.core.entity.NcloudSysNotifyUserEntity;
import com.platform.core.entity.QNcloudSysNotifyEntity;
import com.platform.core.entity.SysDataStandardEntity;
import com.platform.core.repository.NcloudSysNotifyRepository;
import com.platform.core.service.NcloudSysNotifyBiz;
import com.platform.core.service.NcloudSysNotifyUserBiz;
import com.platform.core.service.SysUserService;
import com.platform.dto.NcloudSysNotifyDto;
import com.platform.dto.UserQo;
import com.platform.enums.SysNotifyType;
import com.platform.enums.SysNotifyUserType;
import com.querydsl.core.BooleanBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Description: DirNotify-业务接口实现类
 *
 * @author zq
 */
@Slf4j
@Service
public class NcloudSysNotifyBizImpl extends BaseEntityBizImpl<NcloudSysNotifyRepository, NcloudSysNotifyEntity>
        implements NcloudSysNotifyBiz {

    private final QNcloudSysNotifyEntity qDirNotify = QNcloudSysNotifyEntity.dirNotifyEntity;
    private final DtoMapper mapper;
    private final NcloudSysNotifyUserBiz ncloudSysNotifyUserBiz;
    private final ICommDataInfoBiz commDataInfoBiz;
    private final SysUserService sysUserService;
    private final TokenInfoUtil tokenInfoUtil;


    public NcloudSysNotifyBizImpl(NcloudSysNotifyRepository ncloudSysNotifyRepository,
                                  DtoMapper mapper, NcloudSysNotifyUserBiz ncloudSysNotifyUserBiz,
                                  ICommDataInfoBiz commDataInfoBiz,SysUserService sysUserService,
                                  TokenInfoUtil tokenInfoUtil) {
        super(ncloudSysNotifyRepository);
        this.mapper = mapper;
        this.ncloudSysNotifyUserBiz = ncloudSysNotifyUserBiz;
        this.commDataInfoBiz = commDataInfoBiz;
        this.sysUserService = sysUserService;
        this.tokenInfoUtil = tokenInfoUtil;
    }

    @Override
    public Page<NcloudSysNotifyDto> search(Map<String, String> params, Pageable pageable) {
        String status = Optional.ofNullable(params).map(map -> map.get("status")).orElse("");
        BooleanBuilder builder = new BooleanBuilder();
        if (StrUtil.isNotEmpty(params.get("title"))){
            builder.and(qDirNotify.title.contains(params.get("title")));
        }
        if (StrUtil.isNotEmpty(status)){
            builder.and(qDirNotify.status.eq(status));
        }
        if (StrUtil.isNotEmpty(params.get("type"))){
            builder.and(qDirNotify.type.eq(params.get("type")));
        }
        Page<NcloudSysNotifyEntity> page = queryByPage(builder, pageable);
        return page.map(entity -> {
            NcloudSysNotifyDto sysNotifyDto = mapper.map(entity, NcloudSysNotifyDto.class);
            UserQo byUserId = sysUserService.getByUserId(sysNotifyDto.getCreateBy());
            sysNotifyDto.setCreateBy(byUserId.getUsername());
            return getFileListByAttach(sysNotifyDto);
        });
    }

    public NcloudSysNotifyDto getFileListByAttach(NcloudSysNotifyDto temp){
        // 添加附件ids
        String attachments = temp.getAttachment();
        if (!Strings.isNullOrEmpty(attachments)) {
            String[] file = attachments.split(",");
            List<Map<String, String>> fileList = com.google.common.collect.Lists.newArrayList();
            for (String fileId : file) {
                CommDataInfoEntity commDataInfo = commDataInfoBiz.queryCommDataImpById(fileId);
                if (Objects.nonNull(commDataInfo)) {
                    Map<String, String> fileMap = Maps.newHashMap();
                    fileMap.put("id", fileId);
                    fileMap.put("fileName", commDataInfo.getFileName());
                    fileList.add(fileMap);
                }
            }
            temp.setFileList(fileList);
        }
        return temp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Map<String, String> map) {
        repository.deleteById(MapUtils.getString(map,"id"));
        ncloudSysNotifyUserBiz.removeByNotifyId(MapUtils.getString(map,"id"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publish(Map<String, String> map) {
        NcloudSysNotifyEntity entity = fetchById(MapUtils.getString(map,"id"));
        entity.setStatus("audited");
        entity.setUpdateDate(LocalDateTime.now());
        saveEntity(entity);
        List<String> collect = sysUserService.getByUserAll().stream().map(UserQo::getId).collect(Collectors.toList());
        ncloudSysNotifyUserBiz.saveAll(collect.stream().map(userId -> {
            NcloudSysNotifyUserEntity ncloudSysNotifyUserEntity = new NcloudSysNotifyUserEntity();
            ncloudSysNotifyUserEntity.setNotifyId(entity.getId());
            ncloudSysNotifyUserEntity.setUserId(userId);
            ncloudSysNotifyUserEntity.setStatus(SysNotifyUserType.UNREAD.name());
            ncloudSysNotifyUserEntity.setUpdateDate(LocalDateTime.now());
            return ncloudSysNotifyUserEntity;
        }).collect(Collectors.toList()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public NcloudSysNotifyDto detail(String id) {
        return queryOne(qDirNotify.id.eq(id))
                .map(entity -> {
                    NcloudSysNotifyDto dto = mapper.map(entity, NcloudSysNotifyDto.class);
                    UserQo byUserId = sysUserService.getByUserId(dto.getCreateBy());
                    dto.setCreateBy(byUserId.getUsername());
                    return getFileListByAttach(dto);
                })
                .orElse(null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public NcloudSysNotifyDto add(NcloudSysNotifyDto req) {
        NcloudSysNotifyEntity entity = mapper.map(req, NcloudSysNotifyEntity.class);
        if (StrUtil.isBlank(entity.getContent())){
            entity.setContent(entity.getTitle());
        }
        entity.setStatus("edit");
        entity.setCreateBy(tokenInfoUtil.getUser().getId());
        List<String> attachIds = Lists.newArrayList();
        req.getFileList().forEach(attach -> attachIds.add(attach.get("id")));
        entity.setAttachment(Joiner.on(",").join(attachIds));
        NcloudSysNotifyEntity ncloudSysNotifyEntity = saveEntity(entity);
        return mapper.map(ncloudSysNotifyEntity,NcloudSysNotifyDto.class);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public NcloudSysNotifyDto modify(NcloudSysNotifyDto req) {
        NcloudSysNotifyEntity entity = fetchById(req.getId());
        mapper.map(req, entity);
        List<String> attachIds = Lists.newArrayList();
        // 存储附件信息
        req.getFileList().forEach(attach -> attachIds.add(attach.get("id")));
        entity.setAttachment(Joiner.on(",").join(attachIds));
        entity.setUpdateDate(LocalDateTime.now());
        saveEntity(entity);
        return mapper.map(entity, NcloudSysNotifyDto.class);
    }
}
